/**
 * CopyClone.java created by zhangzhidong 
 * at 下午2:57:29 2016年10月17日
 */
package jdk.effectivejava;

class Person{
	private String name;
	private int age;
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * @return the age
	 */
	public int getAge() {
		return age;
	}
	/**
	 * @param age the age to set
	 */
	public void setAge(int age) {
		this.age = age;
	}
	
}
class Worker implements Cloneable{
	private String workAddr;
	private int workNum;
	private Person p;
	/**
	 * @param workAddr
	 * @param workNum
	 * @param p
	 */
	public Worker(String workAddr, int workNum, String name,int age) {
		super();
		this.workAddr = workAddr;
		this.workNum = workNum;
		this.p = new Person(name, age);
	}
	
	public Object clone(){
		try{
			return super.clone();
		}catch (Exception e ){
			return null;
		}
	}
	public Object clone(int version){
		Worker worker = new Worker(workAddr, workNum, p.getName(),p.getAge());
		return worker;
	}

	/**
	 * @return the workAddr
	 */
	public String getWorkAddr() {
		return workAddr;
	}

	/**
	 * @param workAddr the workAddr to set
	 */
	public void setWorkAddr(String workAddr) {
		this.workAddr = workAddr;
	}

	/**
	 * @return the workNum
	 */
	public int getWorkNum() {
		return workNum;
	}

	/**
	 * @param workNum the workNum to set
	 */
	public void setWorkNum(int workNum) {
		this.workNum = workNum;
	}

	/**
	 * @return the p
	 */
	public Person getP() {
		return p;
	}

	/**
	 * @param p the p to set
	 */
	public void setP(Person p) {
		this.p = p;
	}
}
public class CopyClone {
	public static void main(String args[]){
		Worker w = new Worker("wudaokou", 73, "xiaoming", 23);
		Worker workCloneV1 = (Worker)w.clone();
//		workCloneV1.setWorkAddr(new String("wudaokou"));
		System.out.println("String field equal? "+(w.getWorkAddr()==workCloneV1.getWorkAddr()));
		Worker workCloneV2 = (Worker)w.clone(3);
		System.out.println("original obj equals with the cloned obj v1:"+(w==workCloneV1)+",equals with the cloned obj v2:"+(w==workCloneV2));
		//false  false
		System.out.println(w.getP() == workCloneV1.getP());
		//true
		System.out.println(w.getP() == workCloneV2.getP());
		//fasle
		w.setWorkAddr("zhongguancun");
		w.setWorkNum(13);
		w.getP().setAge(13);
		w.getP().setName("xiaogang");
		System.out.println(w.getP().getName());
		//xiaogang
		System.out.println(workCloneV1.getP().getName());
		//xiaogang
		System.out.println(workCloneV2.getP().getName());
		//xiaoming
		System.out.println(w.getWorkAddr()==workCloneV1.getWorkAddr());
		//ture

		
		AA a = new AA("test");
		AA b = (AA) a.clone();
		System.out.println("String field equal? "+(a.field == b.field));
		a.field = "test";
		System.out.println("String field equal? "+(a.field == b.field));
		a.field = new String("test");
		System.out.println("String field equal? "+(a.field == b.field));
		
		AA arr [] = new AA[2];
		arr[0] = new AA("aa0");
		arr[1] = new AA("aa1");
		
		AA clo[] = arr.clone();
		System.out.println(arr[0]==clo[0]);//true
		System.out.println(arr[1]==clo[1]);//true
		
		
	}
	
}
class AA implements Cloneable{
	public String field;
	public AA(String field) {
		super();
		this.field = field;
	}
	public Object clone(){
		try{
			return super.clone();
		}catch(Exception e){
			return null;
		}
	}
}

